using System.Linq;
using FireStarter.Base;
using FireStarter.Base.BusinessObjectMerger;
using FireStarterModeller.BO;
using FireStarterModeller.Logic.MergeBusinessObjects;
using FireStarterModeller.Test.BO;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.Logic.MergeBusinessObjects
{
    // ReSharper disable InconsistentNaming
    [TestFixture]
    public class TestMergeUIColumnLayout
    {
        [TestFixtureSetUp]
        public virtual void TestFixtureSetup()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public virtual void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        [Test]
        public void Test_MergeUIColumnLayout_ShouldMergeUIFields()

        {
            //---------------Set up test pack-------------------
            var uiColumnLayoutMerger = MergeableBORegistry.Instance.Resolve<UIColumnLayout>();
            var fromUIColumnLayout = TestUtilsUIColumnLayout.GetFactory()
                    .WithMany(columnLayout => columnLayout.UIFields)
                    .WithOutSingleRelationships()
                    .CreateValidBusinessObject();
            var uiFields = fromUIColumnLayout.UIFields;
            SetPropertyName(uiFields[0]);
            SetPropertyName(uiFields[1]);
            SetPropertyName(uiFields[2]);
            var toUIColumnLayout = new UIColumnLayout();
            //---------------Assert Precondition----------------
            Assert.Greater(fromUIColumnLayout.UIFields.Count, 2);
            Assert.AreEqual(0, toUIColumnLayout.UIFields.Count);
            //---------------Execute Test ----------------------
            uiColumnLayoutMerger.MergeBOFrom(fromUIColumnLayout, toUIColumnLayout);
            //---------------Test Result -----------------------
            Assert.AreEqual(fromUIColumnLayout.UIFields.Count, toUIColumnLayout.UIFields.Count);
            Assert.AreEqual(3, toUIColumnLayout.UIFields.Count);
        }

        private static void SetPropertyName(UIField uiField)
        {
            uiField.PropertyName = TestUtilsShared.GetRandomString();
        }

        [Test]
        public void Test_MergeUIColumnLayout_WhenTwoUpdatedFields_ShouldUpdateFields()
        {
            //---------------Set up test pack-------------------
            var uiColumnLayoutMerger = MergeableBORegistry.Instance.Resolve<UIColumnLayout>();
            var fromUIColumnLayout = TestUtilsUIColumnLayout.GetFactory()
                .WithTwo(columnLayout => columnLayout.UIFields)
                .WithOutSingleRelationships()
                .CreateValidBusinessObject();
            var uiFields = fromUIColumnLayout.UIFields;
            var fromUIField = uiFields[0];
            SetPropertyName(fromUIField);
            var fromUIField2 = uiFields[1];
            SetPropertyName(fromUIField2);

            var toUIColumnLayout = new UIColumnLayout();
            UIField expectedToUIField = AddCopiedUIField(toUIColumnLayout, fromUIField);
            UIField expectedToUIField2 = AddCopiedUIField(toUIColumnLayout, fromUIField2);

            //---------------Assert Precondition----------------
            Assert.AreEqual(2, fromUIColumnLayout.UIFields.Count);
            Assert.AreNotEqual(fromUIField.LabelText, expectedToUIField.LabelText);
            Assert.AreNotEqual(fromUIField2.LabelText, expectedToUIField2.LabelText);
            //---------------Execute Test ----------------------
            uiColumnLayoutMerger.MergeBOFrom(fromUIColumnLayout, toUIColumnLayout);
            //---------------Test Result -----------------------
            Assert.IsNotNull(toUIColumnLayout);
            Assert.AreEqual(2, toUIColumnLayout.UIFields.Count);
            var toUIField = toUIColumnLayout.UIFields.First();
            //  Assert.AreSame(expectedToUIField, toUIField);
            Assert.AreEqual(fromUIField.PropertyName, toUIField.PropertyName);
            Assert.AreEqual(fromUIField.LabelText, toUIField.LabelText);
            var toUIField2 = toUIColumnLayout.UIFields.Last();
            //   Assert.AreSame(expectedToUIField2, toUIField2);
            Assert.AreEqual(fromUIField2.PropertyName, toUIField2.PropertyName);
            Assert.AreEqual(fromUIField2.LabelText, toUIField2.LabelText);
        }


        private static UIField AddCopiedUIField(UIColumnLayout toUIColumnLayout, UIField fromUIfield)
        {
            var expectedToUIField = new UIField { PropertyName = fromUIfield.PropertyName};
            expectedToUIField.LabelText = TestUtilsShared.GetRandomString();
            toUIColumnLayout.UIFields.Add(expectedToUIField);
            return expectedToUIField;
        }

        private static UIField CreateUIField(UIColumnLayout uiColumnLayout)
        {
            var uiField = uiColumnLayout.UIFields.CreateBusinessObject();
            uiField.PropertyName = TestUtilsShared.GetRandomString();
            uiField.LabelText = TestUtilsShared.GetRandomString();
            return uiField;
        }


        [Test]
        public void Test_MergeUIColumnLayout_WhenOneRemovedUiField_ShouldUpdateFieldStatusToDelete()
        {
            //---------------Set up test pack-------------------
            var uiColumnLayoutMerger = MergeableBORegistry.Instance.Resolve<UIColumnLayout>();
            var fromUIColumnLayout = new UIColumnLayout();
            var fromUIField = CreateUIField(fromUIColumnLayout);
            var fromUIField2 = CreateUIField(fromUIColumnLayout);
            var toUIColumnLayout = new UIColumnLayout();
            UIField expectedToUIField = AddCopiedUIField(toUIColumnLayout, fromUIField);
            UIField expectedToUIField2 = AddCopiedUIField(toUIColumnLayout, fromUIField2);
            fromUIColumnLayout.UIFields.Remove(fromUIField2);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, fromUIColumnLayout.UIFields.Count);
            Assert.AreEqual(2, toUIColumnLayout.UIFields.Count);
            Assert.AreNotEqual(fromUIField.LabelText, expectedToUIField.LabelText);
            Assert.AreNotEqual(ChangeType.Update, expectedToUIField.PendingChangeType);
            Assert.AreNotEqual(ChangeType.Delete, expectedToUIField2.PendingChangeType);
            //---------------Execute Test ----------------------
            uiColumnLayoutMerger.MergeBOFrom(fromUIColumnLayout, toUIColumnLayout);
            //---------------Test Result -----------------------

            Assert.IsNotNull(toUIColumnLayout);
            Assert.AreEqual(2, toUIColumnLayout.UIFields.Count);
            var toUIField = toUIColumnLayout.UIFields.First(field => field.PropertyName == fromUIField.PropertyName);
            Assert.AreSame(toUIField, expectedToUIField);

            var toUIField2 = toUIColumnLayout.UIFields.Last(field => field.PropertyName == fromUIField2.PropertyName);
            Assert.AreSame(toUIField2, expectedToUIField2);
            Assert.AreEqual(ChangeType.None, toUIField.PendingChangeType);
            Assert.AreEqual(ChangeType.Delete, toUIField2.PendingChangeType);
        }

        [Test]
        public void Test_MergeUIColumnLayout_WhenMergeToNotNull_ShouldUpdateUIColumnLayout()
        {
            //---------------Set up test pack-------------------
            IMergeBO<UIColumnLayout> mergeBO = MergeableBORegistry.Instance.Resolve<UIColumnLayout>();
            var fromUIColumnLayout = TestUtilsUIColumnLayout.GetFactory()
                .WithMany(columnLayout => columnLayout.UIFields)
                .WithOutSingleRelationships()
                .CreateValidBusinessObject();
            fromUIColumnLayout.Width = TestUtilsShared.GetRandomInt();
            var toUiField = new UIColumnLayout();
            //---------------Assert Precondition----------------
            Assert.AreNotEqual(fromUIColumnLayout.Width, toUiField.Width);
            //---------------Execute Test ----------------------
            mergeBO.MergeBOFrom(fromUIColumnLayout, toUiField);
            //---------------Test Result -----------------------
            Assert.AreEqual(fromUIColumnLayout.Width, toUiField.Width);
        }
      

    }
    // ReSharper restore InconsistentNaming
}